package org.jeecg.modules.foc.controller;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.c.entity.*;
import org.jeecg.modules.c.service.*;
import org.jeecg.modules.c.service.impl.MDeviceServiceImpl;
import org.jeecg.modules.common.FocCacheConstant;
import org.jeecg.modules.foc.FocSpaceTreeDTO;
import org.jeecg.modules.foc.entity.FocDevice;
import org.jeecg.modules.foc.entity.FocPoint;
import org.jeecg.modules.foc.entity.FocSpace;
import org.jeecg.modules.foc.service.IFocDeviceService;
import org.jeecg.modules.foc.service.IFocPointService;
import org.jeecg.modules.foc.service.IFocSpaceService;

import java.util.Date;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @Description: 空间管理
 * @Author: jeecg-boot
 * @Date: 2025-01-10
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "空间管理")
@RestController
@RequestMapping("/foc/focSpace")
public class FocSpaceController extends JeecgController<FocSpace, IFocSpaceService> {
    @Autowired
    private IFocSpaceService focSpaceService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IFocDeviceService focDeviceService;

    @Autowired
    private IMDeviceService mDeviceService;
    @Autowired
    private IMSignalService mSignalService;

    @Autowired
    private IFocPointService focPointService;
    @Autowired
    private IMAreaService mAreaService;
    @Autowired
    private IMSiteService mSiteService;
    @Autowired
    private IMRoomService mRoomService;

    /**
     * 分页列表查询
     *
     * @param focSpace
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "空间管理-分页列表查询")
    @ApiOperation(value = "空间管理-分页列表查询", notes = "空间管理-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(FocSpace focSpace,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<FocSpace> queryWrapper = QueryGenerator.initQueryWrapper(focSpace, req.getParameterMap());
        Page<FocSpace> page = new Page<FocSpace>(pageNo, pageSize);
        IPage<FocSpace> pageList = focSpaceService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 分页列表查询
     *
     * @param 2focSpace
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "空间管理-获取当前空间节点父子结构")
    @ApiOperation(value = "空间管理-获取当前空间节点父子结构", notes = "空间管理-获取当前空间节点父子结构")
    @GetMapping(value = "/getSPaceTree")
    @Cacheable(value = FocCacheConstant.FOC_SPEACE_CACHE, key = "'" + FocCacheConstant.FOC_SPEACE_CACHE + "'")
    public Result<?> getSPaceTree() {

        //查询根节点
        //缓存中存在直接查询返回

        QueryWrapper<FocSpace> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_guid", "-1");
        List<FocSpace> list = focSpaceService.list(queryWrapper);
        //将父节点转为dto

        List<FocSpaceTreeDTO> focSpaceTreeDTOS = BeanUtil.copyToList(list, FocSpaceTreeDTO.class);
        for (FocSpaceTreeDTO focSpaceTreeDTO : focSpaceTreeDTOS) {
            /**
             * 根据父节点查询子节点
             */
            focSpaceService.getSpaceTree(focSpaceTreeDTO);
        }
        //根据
        return Result.OK(focSpaceTreeDTOS);
    }


    /**
     * 添加
     *
     * @param focSpace
     * @return
     */
    @AutoLog(value = "空间管理-添加")
    @ApiOperation(value = "空间管理-添加", notes = "空间管理-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody FocSpace focSpace) {
        focSpaceService.save(focSpace);
        return Result.OK("添加成功！");
    }


    /**
     * 取消关联
     *
     * @param focSpace
     * @return
     */
    @AutoLog(value = "空间管理-取消关联")
    @ApiOperation(value = "空间管理-取消关联", notes = "空间管理-取消关联")
    @PostMapping(value = "/cancleMapping")
    public Result<?> cancleMapping(@RequestBody FocSpace focSpace) {
        focSpaceService.cancleMapping(focSpace);
        return Result.OK("取消成功！");
    }

    /**
     * 编辑
     *
     * @param focSpace
     * @return
     */
    @AutoLog(value = "空间管理-编辑")
    @ApiOperation(value = "空间管理-编辑", notes = "空间管理-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    @Transactional(rollbackFor = Exception.class)
    public Result<?> edit(@RequestBody FocSpace focSpace) {
        ThreadUtil.execAsync(() -> {
            FocSpace oldSpec = focSpaceService.getById(focSpace.getId());
            switch (focSpace.getType()) {
                case 1:
                    //更新区域信息
                    focSpaceService.updateById(focSpace);
                    //获取关联的所有地级市
                    QueryWrapper<FocSpace> focSpaceQueryWrapper = new QueryWrapper<>();
                    focSpaceQueryWrapper.eq("`parent_guid`", focSpace.getGuid());
                    focSpaceQueryWrapper.eq("`type`", 2);
                    List<FocSpace> oldCityList = focSpaceService.list(focSpaceQueryWrapper);
                    for (FocSpace space : oldCityList) {
                        focSpaceService.toSpeaceConvert(space);
                    }
                    focSpaceService.toSpeaceConvert(focSpace);
                    //判断编码是否存在映射，不存在则进行删除
                    if (StringUtils.isNotEmpty(oldSpec.getAreaid())) {
                        QueryWrapper<FocSpace> areaInfoQueryWrapper = new QueryWrapper<>();
                        areaInfoQueryWrapper.eq("areaid", oldSpec.getAreaid());
                        List<FocSpace> oldAreaList = focSpaceService.list(areaInfoQueryWrapper);
                        if (CollectionUtil.isEmpty(oldAreaList)) {
                            QueryWrapper<MArea> mAreaQueryWrapper = new QueryWrapper<>();
                            mAreaQueryWrapper.eq("areaid", oldSpec.getAreaid());
                            mAreaService.remove(mAreaQueryWrapper);
                        }
                    }
                    break;
                case 2:
                    //更新城市信息
                    //获取关联的所有县
                    focSpaceService.updateById(focSpace);
                    QueryWrapper<FocSpace> focAreaWrapper = new QueryWrapper<>();
                    focAreaWrapper.eq("`parent_guid`", focSpace.getGuid());
                    focAreaWrapper.eq("`type`", 3);
                    List<FocSpace> oldCountyList = focSpaceService.list(focAreaWrapper);
                    for (FocSpace space : oldCountyList) {
                        focSpaceService.toSpeaceConvert(space);
                    }
                    focSpaceService.toSpeaceConvert(focSpace);
                    if (StringUtils.isNotEmpty(oldSpec.getAreaid())) {
                        List<FocSpace> oldAreaList = focSpaceService.list(new QueryWrapper<FocSpace>().eq("areaid", oldSpec.getAreaid()));      
                        if (CollectionUtil.isEmpty(oldAreaList)) {
                            QueryWrapper<MArea> mAreaQueryWrapper = new QueryWrapper<>();
                            mAreaQueryWrapper.eq("areaid", oldSpec.getAreaid());
                            mAreaService.remove(mAreaQueryWrapper);
                        }
                    }
                    break;
                case 3:
                    //更新区信息
                    //获取老区域关联的所有局站
                    QueryWrapper<FocSpace> oldSide = new QueryWrapper();
                    oldSide.eq("`areaid`", oldSpec.getAreaid());
                    oldSide.eq("type", 4);
                    List<FocSpace> oldSides = focSpaceService.list(oldSide);
                    //更新所有局站的区域,单独设置
                    for (FocSpace side : oldSides) {
                        side.setAreaid(focSpace.getAreaid());
                        side.setAreaname(focSpace.getAreaname());
                        focSpaceService.updateById(side);
                        focSpaceService.toSpeaceConvert(side);
                    }
                    //获取未设置的局站
                    QueryWrapper<FocSpace> newSide = new QueryWrapper();
                    newSide.eq("parent_guid", oldSpec.getGuid());
                    newSide.eq("type", 4);
                    newSide.isNull("areaid");
                    List<FocSpace> newSides = focSpaceService.list(newSide);
                    focSpaceService.updateById(focSpace);
                    //编辑空间时，当映射字段不为空时直接进行转换
                    focSpaceService.toSpeaceConvert(focSpaceService.getById(focSpace.getId()));
                    for (FocSpace side : newSides) {
                        focSpaceService.toSpeaceConvert(side);
                    }
                    redisUtil.removeAll("foc:speace");
                    if (StringUtils.isNotEmpty(oldSpec.getAreaid())) {
                        focSpaceService.list(new QueryWrapper<FocSpace>().eq("areaid", oldSpec.getAreaid()));
                        List<FocSpace> oldAreaList = focSpaceService.list(new QueryWrapper<FocSpace>().eq("areaid", oldSpec.getAreaid()));
                        if (CollectionUtil.isEmpty(oldAreaList)) {
                            QueryWrapper<MArea> mAreaQueryWrapper = new QueryWrapper<>();
                            mAreaQueryWrapper.eq("areaid", oldSpec.getAreaid());
                            mAreaService.remove(mAreaQueryWrapper);
                        }
                    }
                    break;
                    // return Result.OK("编辑成功!");
                case 4:
                    //更新局站关联的所有站点
                    QueryWrapper<FocSpace> oldSiteQuery = new QueryWrapper();
                    oldSiteQuery.eq("`siteid`", oldSpec.getSiteid());
                    oldSiteQuery.eq("type", 5);
                    List<FocSpace> oldSites = focSpaceService.list(oldSiteQuery);
                    for (FocSpace site : oldSites) {
                        site.setSiteid(focSpace.getSiteid());
                        site.setSitename(focSpace.getSitename());
                        focSpaceService.updateById(site);
                        focSpaceService.toSpeaceConvert(site);
                    }
                    //获取未设置的机房
                    QueryWrapper<FocSpace> newRoomQuery = new QueryWrapper();
                    newRoomQuery.eq("parent_guid", oldSpec.getGuid());
                    newRoomQuery.isNull("siteid");
                    newRoomQuery.eq("type", 5);
                    List<FocSpace> newSites = focSpaceService.list(newRoomQuery);
                    focSpaceService.updateById(focSpace);
                    focSpaceService.toSpeaceConvert(focSpace);
                    for (FocSpace site : newSites) {
                        focSpaceService.toSpeaceConvert(site);
                        //获取机房下的所有设备
                        QueryWrapper<FocDevice> focdecieQuery = new QueryWrapper<>();
                        focdecieQuery.eq("parent_guid", site.getGuid());
                        //已映射的设备
                        focdecieQuery.isNotNull("deviceid");
                        List<FocDevice> list = focDeviceService.list(focdecieQuery);
                        for (FocDevice focDevice : list) {
                            //对设备重新进行映射
                            focDeviceService.toDeviceConvert(focDevice);
                            //操作完设备后，操作信号
                            //获取所有已经映射的信号
                            QueryWrapper<FocPoint> focSignalQueryWrapper = new QueryWrapper<>();
                            focSignalQueryWrapper.eq("parent_guid", focDevice.getGuid());
                            focSignalQueryWrapper.isNotNull("mp_code");
                            List<FocPoint> focSignals = focPointService.list(focSignalQueryWrapper);
                            for (FocPoint focSignal : focSignals) {
                                focPointService.toPointConver(focSignal);
                            }
                        }
                    }
                    //编码不存在进行删除
                    if (StringUtils.isNotEmpty(oldSpec.getSiteid())) {

                        List<FocSpace> oldSiteList = focSpaceService.list(new QueryWrapper<FocSpace>().eq("siteid", oldSpec.getSiteid()));
                        if (CollectionUtil.isEmpty(oldSiteList)) {
                            QueryWrapper<MSite> mSiteQueryWrapper = new QueryWrapper<>();
                            mSiteQueryWrapper.eq("siteid", oldSpec.getSiteid());


                            mSiteService.remove(mSiteQueryWrapper);

                        }
                    }
                        break;

                    //return Result.OK("编辑成功!");
                case 5:
                    //更新机房信息,单独设置
                    FocSpace oldRoom = focSpaceService.getById(focSpace.getId());
                    //更新站点关联的所有设备
                    QueryWrapper<FocDevice> oldRoomQuery = new QueryWrapper();
                    oldRoomQuery.eq("`roomid`", oldRoom.getRoomid());
                    List<FocDevice> oldDevices = focDeviceService.list(oldRoomQuery);
                    for (FocDevice device : oldDevices) {
                        device.setRoomid(focSpace.getRoomid());
                        device.setRoomName(focSpace.getRoomName());
                        focDeviceService.updateById(device);
                        focDeviceService.toDeviceConvert(device);
                    }
                    //获取未设置的设备
                    QueryWrapper<FocDevice> newDeviceQuery = new QueryWrapper();
                    newDeviceQuery.eq("parent_guid", oldSpec.getGuid());
                    newDeviceQuery.isNull("roomid");
                    List<FocDevice> newDevices = focDeviceService.list(newDeviceQuery);
                    focSpaceService.updateById(focSpace);
                    for (FocDevice device : newDevices) {
                        focDeviceService.toDeviceConvert(device);
                    }
                    focSpaceService.toSpeaceConvert(focSpace);
                    //编码不存在则进行删除
                    if (StringUtils.isNotEmpty(oldSpec.getRoomid())) {
                     
                        List<FocSpace> oldRoomList = focSpaceService.list(new QueryWrapper<FocSpace>().eq("roomid", oldSpec.getRoomid()));
                        if (CollectionUtil.isEmpty(oldRoomList)) {
                            QueryWrapper<MRoom> mRoomQueryWrapper = new QueryWrapper<>();
                            mRoomQueryWrapper.eq("roomid", oldSpec.getRoomid());
                            mRoomService.remove(mRoomQueryWrapper);
                        }
                    }

                break;
            }
            redisUtil.removeAll("foc:speace");
        });

        return Result.OK("编辑成功!");

    }

    /**
     * gu=
     *
     * @param id
     * @return
     */
    @AutoLog(value = "空间管理-通过id删除")
    @ApiOperation(value = "空间管理-通过id删除", notes = "空间管理-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        focSpaceService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "空间管理-批量删除")
    @ApiOperation(value = "空间管理-批量删除", notes = "空间管理-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.focSpaceService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功！");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "空间管理-通过id查询")
    @ApiOperation(value = "空间管理-通过id查询", notes = "空间管理-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        FocSpace focSpace = focSpaceService.getById(id);
        return Result.OK(focSpace);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param focSpace
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, FocSpace focSpace) {
        return super.exportXls(request, focSpace, FocSpace.class, "空间管理");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, FocSpace.class);
    }

}
